#include <stdlib.h>
#include <string.h>
#include "design.h"

void init_solution (struct solution *solution)
{
	solution->max = solution->curr = 0;
	solution->edge = NULL;
}

void free_solution (struct solution *solution)
{
	solution->max = solution->curr = 0;
	free (solution->edge);
}

struct solve_static *init_solve_static (int N)
{
	struct solve_static *solve;

	solve = calloc (sizeof (struct solve_static), 1);

	int i;

	solve->Og = calloc (sizeof (int), N);
	solve->Or = calloc (sizeof (int), N);
	solve->Rg0 = calloc (sizeof (int), N);
	solve->Rr0 = calloc (sizeof (int), N);
	solve->edge = calloc (sizeof (int), N);

	for (i = 0; i < N; i++)
	{
		solve->Og[i] = 0;
		solve->Or[i] = 0;
	}

	return solve;
}

void free_solve_static (struct solve_static *solve)
{
	free (solve->Og);
	free (solve->Or);
	free (solve->Rg0);
	free (solve->Rr0);
	free (solve->edge);
	free (solve);
}

struct solve_dynamic *init_solve_dynamic (int N)
{
	struct solve_dynamic *solve;

	solve = calloc (sizeof (struct solve_dynamic), 1);

	int i;

	solve->Rg = calloc (sizeof (int), N);
	solve->Rr = calloc (sizeof (int), N);
	solve->Fg = calloc (sizeof (int), N);
	solve->Fr = calloc (sizeof (int), N);
	solve->order = calloc (sizeof (int), N);
	solve->edge = calloc (sizeof (int), N);
	solve->Og = calloc (sizeof (int), N);
	solve->Or = calloc (sizeof (int), N);

	for (i = 0; i < N; i++)
	{
		solve->Rg[i] = 0;
		solve->Rr[i] = 0;
		solve->Fg[i] = 0;
		solve->Fr[i] = 0;
		solve->order[i] = i;
	}

	return solve;
}

void copy_solve_dynamic (int N, struct solve_dynamic *solve1, struct solve_dynamic *solve2)
{
	memcpy (solve2->Rg, solve1->Rg, sizeof (int) * N);
	memcpy (solve2->Rr, solve1->Rr, sizeof (int) * N);
	memcpy (solve2->Fg, solve1->Fg, sizeof (int) * N);
	memcpy (solve2->Fr, solve1->Fr, sizeof (int) * N);
	memcpy (solve2->order, solve1->order, sizeof (int) * N);
}

void free_solve_dynamic (struct solve_dynamic *solve)
{
	free (solve->Rg);
	free (solve->Rr);
	free (solve->Fg);
	free (solve->Fr);
	free (solve->order);
	free (solve->edge);
	free (solve->Og);
	free (solve->Or);
	free (solve);
}

void combine_dist (int N1, int N2, int dist[N2 + 1], double Dist[N1 * N2 + 1], int i)
{
	int j, k;
	double Dist2[N1 * N2 + 1];

	if (i == 0)
	{
		for (j = 0; j <= N1 * N2; j++)
			Dist[j] = 0.0;

		for (j = 0; j <= N2; j++)
			Dist[j] = dist[j];
	}
	else
	{
		for (j = 0; j <= (i + 1) * N2; j++)
		{
			Dist2[j] = 0.0;
			if (j <= N2)
			{
				for (k = 0; k <= j; k++)
				{
					Dist2[j] += dist[k] * Dist[j - k];
				}
			}
			else
			{
				for (k = 0; k <= N2; k++)
				{
					Dist2[j] += dist[k] * Dist[j - k];
				}
			}
		}

		for (j = 0; j <= (i + 1) * N2; j++)
		{
			Dist[j] = Dist2[j];
		}
	}
}
